home *** CD-ROM | disk | FTP | other *** search
Text File | 1991-08-22 | 64.0 KB | 2,665 lines |
- This is a new archive version of TRN at patchlevel 3.
- The original posting took up Volume23, issues 60 to 73, with
- various problems. These files replace those issues.
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then feed it
- # into a shell via "sh file" or similar. To overwrite existing files,
- # type "sh file -c".
- # The tool that generated this appeared in the comp.sources.unix newsgroup;
- # send mail to comp-sources-unix@uunet.uu.net if you want that tool.
- # Contents: art.c ng.c
- # Wrapped by rsalz@litchi.bbn.com on Fri Aug 23 16:38:53 1991
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- echo If this archive is complete, you will see the following message:
- echo ' "shar: End of archive 4 (of 14)."'
- if test -f 'art.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'art.c'\"
- else
- echo shar: Extracting \"'art.c'\" \(26201 characters\)
- sed "s/^X//" >'art.c' <<'END_OF_FILE'
- X/* $Header: art.c,v 4.3.3.3 91/01/16 02:20:45 davison Trn $
- X *
- X * $Log: art.c,v $
- X * Revision 4.3.3.3 91/01/16 02:20:45 davison
- X * Integrated rn patches 48-54.
- X *
- X * Revision 4.3.3.2 90/08/20 16:05:33 davison
- X * Fixed bug in backpage code.
- X *
- X * Revision 4.3.3.1 90/06/20 22:35:51 davison
- X * Initial Trn Release
- X *
- X * Revision 4.3.2.9 90/12/10 01:34:42 sob
- X * "8 bit clean" mods and fixes for rn -e -L problems.
- X *
- X * Revision 4.3.2.8 90/12/04 02:49:12 sob
- X * Added long lost commands control-P and control-N back into rn.
- X *
- X * Revision 4.3.2.7 90/11/22 13:48:59 sob
- X * Added changes that will hopefully fix the "long lines" bug.
- X *
- X * Revision 4.3.2.6 90/10/01 21:14:36 sob
- X * Shifted to fileno to increase portability.
- X *
- X * Revision 4.3.2.5 90/10/01 21:05:22 sob
- X * Removed an extra closing paren.
- X *
- X * Revision 4.3.2.4 90/10/01 02:01:53 sob
- X * Fix provided by earle@sun.com to alter rn's assumption of how to turn
- X * off underline mode when at the end of a line.
- X *
- X * Revision 4.3.2.3 90/04/21 14:43:27 sob
- X * Revised previous patch insure that it does not decrement below zero.
- X *
- X * Revision 4.3.2.2 90/03/22 23:03:25 sob
- X * Fixes provided by Wayne Davison <drivax!davison>
- X *
- X * Revision 4.3.2.1 89/11/07 23:20:57 sob
- X * Bug fixes for NNTP
- X *
- X * Revision 4.3.1.5 85/09/10 11:07:18 lwall
- X * %m not restored on some returns.
- X *
- X * Revision 4.3.1.4 85/05/23 12:13:31 lwall
- X * shouldn't display article that's really a subdirectory.
- X *
- X * Revision 4.3.1.3 85/05/13 09:29:55 lwall
- X * Added CUSTOMLINES option.
- X *
- X * Revision 4.3.1.2 85/05/10 13:46:07 lwall
- X * Fixed header reparse bug on backpage.
- X *
- X * Revision 4.3.1.1 85/05/10 11:30:56 lwall
- X * Branch for patches.
- X *
- X * Revision 4.3 85/05/01 11:34:51 lwall
- X * Baseline for release with 4.3bsd.
- X *
- X */
- X
- X#include "EXTERN.h"
- X#include "common.h"
- X#include "rn.h"
- X#include "ngstuff.h"
- X#include "ngdata.h"
- X#include "head.h"
- X#include "cheat.h"
- X#include "help.h"
- X#include "search.h"
- X#include "artio.h"
- X#include "ng.h"
- X#include "bits.h"
- X#include "final.h"
- X#include "artstate.h"
- X#include "rcstuff.h"
- X#include "term.h"
- X#include "sw.h"
- X#include "util.h"
- X#include "backpage.h"
- X#include "intrp.h"
- X#ifdef USETHREADS
- X#include "rthreads.h"
- X#endif
- X#include "INTERN.h"
- X#include "art.h"
- X
- X/* page_switch() return values */
- X
- X#define PS_NORM 0
- X#define PS_ASK 1
- X#define PS_RAISE 2
- X#define PS_TOEND 3
- X
- Xbool special = FALSE; /* is next page special length? */
- Xint slines = 0; /* how long to make page when special */
- XART_LINE highlight = -1; /* next line to be highlighted */
- Xchar *restart = Nullch; /* if nonzero, the place where last */
- X /* line left off on line split */
- Xchar *blinebeg; /* where in buffer current line began */
- XART_POS alinebeg; /* where in file current line began */
- X
- X#ifdef INNERSEARCH
- XART_POS innersearch = 0; /* artpos of end of line we found */
- X /* for 'g' command */
- XART_LINE isrchline = 0; /* last line to display */
- Xbool hide_everything = FALSE;
- X /* if set, do not write page now, */
- X /* but refresh when done with page */
- XCOMPEX gcompex; /* in article search pattern */
- X#endif
- X
- Xbool firstpage; /* is this the 1st page of article? */
- X
- Xchar art_buf[LBUFLEN]; /* place for article lines */
- X
- Xvoid
- Xart_init()
- X{
- X ;
- X}
- X
- Xint
- Xdo_article()
- X{
- X register char *s;
- X ART_POS artsize; /* size in bytes of article */
- X bool hide_this_line = FALSE; /* hidden header line? */
- X ART_LINE linenum; /* line # on page, 1 origin */
- X#ifdef ULSMARTS
- X bool under_lining = FALSE;
- X /* are we underlining a word? */
- X#endif
- X register char *bufptr = art_buf;
- X /* pointer to input buffer */
- X register int outpos; /* column position of output */
- X static char prompt_buf[64]; /* place to hold prompt */
- X bool notesfiles = FALSE; /* might there be notesfiles junk? */
- X char oldmode = mode;
- X char *ctime();
- X
- X#ifdef INNERSEARCH
- X register int outputok;
- X#endif
- X
- X/* if (fstat(artfp->_file,&filestat)) ... does not work on Apollos */
- X if (fstat(fileno(artfp),&filestat))
- X /* get article file stats */
- X return DA_CLEAN;
- X if ((filestat.st_mode & S_IFMT) != S_IFREG)
- X return DA_NORM;
- X artsize = filestat.st_size;
- X /* from that get article size */
- X sprintf(prompt_buf,
- X "%%sEnd of article %ld (of %ld)--what next? [%%s]",
- X (long)art,(long)lastart); /* format prompt string */
- X prompt = prompt_buf;
- X int_count = 0; /* interrupt count is 0 */
- X firstpage = (topline < 0);
- X for (;;) { /* for each page */
- X#ifdef USETHREADS
- X if (max_tree_lines)
- X init_tree(); /* init tree display */
- X#endif
- X assert(art == openart);
- X if (do_fseek) {
- X#ifdef ASYNC_PARSE
- X parse_maybe(art); /* make sure header is ours */
- X#endif
- X artpos = vrdary(artline);
- X if (artpos < 0)
- X artpos = -artpos; /* labs(), anyone? */
- X if (firstpage)
- X artpos = (ART_POS)0;
- X fseek(artfp,artpos,0);
- X if (artpos < htype[PAST_HEADER].ht_minpos)
- X in_header = SOME_LINE;
- X do_fseek = FALSE;
- X restart = Nullch;
- X }
- X linenum = 1;
- X if (firstpage) {
- X if (firstline) {
- X interp(art_buf, (sizeof art_buf), firstline);
- X#ifdef USETHREADS
- X linenum += tree_puts(art_buf,linenum+topline,0);
- X#else
- X#ifdef CLEAREOL
- X maybe_eol();
- X#endif /* CLEAREOL */
- X fputs(art_buf,stdout) FLUSH;
- X linenum++;
- X#endif
- X artopen(art); /* rewind article in case interp */
- X /* forced a header parse */
- X }
- X else {
- X ART_NUM i;
- X
- X#ifdef USETHREADS
- X if (ThreadedGroup) {
- X int sel, unseen;
- X
- X sel = curr_p_art && (selected_roots[curr_p_art->root] & 1);
- X unseen = !was_read(art);
- X sprintf(art_buf,"%s%s #%ld",ngname,moderated,(long)art);
- X if (selected_root_cnt) {
- X i = selected_count - (unseen && sel);
- X sprintf(art_buf+strlen(art_buf)," (%ld + %ld more)",
- X (long)i,(long)toread[ng] - selected_count
- X - unthreaded - (!sel && unseen));
- X }
- X else if ((i = (ART_NUM)(toread[ng]-unthreaded-unseen)) != 0)
- X sprintf(art_buf+strlen(art_buf)," (%ld more)",(long)i);
- X linenum += tree_puts(art_buf,linenum+topline,0);
- X }
- X else
- X#endif
- X {
- X#ifdef CLEAREOL
- X maybe_eol();
- X#endif /* CLEAREOL */
- X printf("Article %ld",(long)art);
- X i = (ART_NUM)(toread[ng] - 1 + was_read(art));
- X#ifdef DELAYMARK
- X if (i || dmcount) {
- X printf(" (%ld more",(long)i);
- X if (dmcount)
- X printf(" + %ld Marked to return",(long)dmcount);
- X putchar(')');
- X }
- X#else
- X if (i)
- X printf(" (%ld more)",(long)i);
- X#endif
- X if (htype[NGS_LINE].ht_flags & HT_HIDE)
- X printf(" in %s", ngname);
- X fputs(moderated,stdout);
- X fputs(":\n",stdout) FLUSH;
- X linenum++;
- X }
- X }
- X start_header(art);
- X forcelast = FALSE; /* we will have our day in court */
- X restart = Nullch;
- X artline = 0; /* start counting lines */
- X artpos = 0;
- X vwtary(artline,artpos); /* remember pos in file */
- X }
- X for (; /* linenum already set */
- X in_header || (
- X#ifdef INNERSEARCH
- X innersearch ? innermore() :
- X#endif
- X linenum<(firstpage?initlines:(special?slines:LINES)) );
- X linenum++) { /* for each line on page */
- X if (int_count) { /* exit via interrupt? */
- X putchar('\n') FLUSH; /* get to left margin */
- X int_count = 0; /* reset interrupt count */
- X mode = oldmode;
- X special = FALSE;
- X return DA_NORM; /* skip out of loops */
- X }
- X if (restart) { /* did not finish last line? */
- X bufptr = restart; /* then start again here */
- X restart = Nullch; /* and reset the flag */
- X }
- X else { /* not a restart */
- X if (fgets(art_buf,LBUFLEN,artfp)==Nullch) {
- X /* if all done */
- X mode = oldmode;
- X special = FALSE;
- X return DA_NORM; /* skip out of loops */
- X }
- X bufptr = art_buf; /* so start at beginning */
- X art_buf[LBUFLEN-1] = '\0';
- X /* make sure string ends */
- X }
- X blinebeg = bufptr; /* remember where we began */
- X alinebeg = artpos; /* both in buffer and file */
- X if (in_header && bufptr == art_buf) {
- X hide_this_line =
- X parseline(art_buf,do_hiding,hide_this_line);
- X#ifdef USETHREADS
- X if (!in_header) {
- X linenum += finish_tree(linenum+topline);
- X }
- X#endif
- X } else if (notesfiles && do_hiding &&
- X bufptr == art_buf && *art_buf == '#' &&
- X isupper(art_buf[1]) && art_buf[2] == ':' ) {
- X fgets(art_buf,sizeof(art_buf),artfp);
- X if (index(art_buf,'!') != Nullch)
- X fgets(art_buf,sizeof(art_buf),artfp);
- X htype[PAST_HEADER].ht_minpos = ftell(artfp);
- X /* exclude notesfiles droppings */
- X hide_this_line = TRUE; /* and do not print either */
- X notesfiles = FALSE;
- X }
- X#ifdef CUSTOMLINES
- X if (hideline && bufptr == art_buf &&
- X execute(&hide_compex,art_buf) )
- X hide_this_line = TRUE;
- X#endif
- X if (in_header && htype[in_header].ht_flags & HT_MAGIC) {
- X if (in_header == NGS_LINE) {
- X hide_this_line = (index(art_buf,',') == Nullch);
- X }
- X else if (in_header == EXPIR_LINE) {
- X if (!(htype[EXPIR_LINE].ht_flags & HT_HIDE))
- X hide_this_line = (strlen(art_buf) < 10);
- X }
- X else if (in_header == FROM_LINE) {
- X if (do_hiding && (s = index(art_buf+6,'(')) != Nullch) {
- X strcpy(art_buf+6,s+1);
- X if((s = rindex(art_buf+6,')')) != Nullch)
- X *s = '\0';
- X }
- X }
- X#ifdef USETHREADS
- X else if (in_header == DATE_LINE && curr_p_art && do_hiding) {
- X strcpy(art_buf+6,ctime(&curr_p_art->date));
- X }
- X#endif
- X }
- X if (in_header == SUBJ_LINE &&
- X htype[SUBJ_LINE].ht_flags & HT_MAGIC) {
- X /* is this the subject? */
- X int length;
- X
- X length = strlen(art_buf)-1;
- X artline++;
- X art_buf[length] = '\0'; /* wipe out newline */
- X#ifdef NOFIREWORKS
- X no_ulfire();
- X#endif
- X notesfiles =
- X (instr(&art_buf[length-10]," - (nf") != Nullch);
- X#ifdef USETHREADS
- X /* tree_puts(, ,1) underlines subject */
- X linenum += tree_puts(art_buf,linenum+topline,1)-1;
- X#else
- X if (oldsubject) {
- X length += 7;
- X fputs("(SAME) ",stdout);
- X oldsubject = FALSE;
- X }
- X if (length+UG > COLS) { /* rarely true */
- X linenum++;
- X vwtary(artline,vrdary(artline-1)+COLS);
- X artline++;
- X }
- X s = art_buf + 8;
- X *s++ = '\0'; /* make into 2 strings */
- X#ifdef CLEAREOL
- X maybe_eol();
- X#endif /* CLEAREOL */
- X fputs(art_buf,stdout) FLUSH;
- X /* print up through : */
- X if (!UG)
- X putchar(' ');
- X underprint(s); /* print subject underlined */
- X putchar('\n') FLUSH; /* and finish the line */
- X#endif
- X }
- X else if (hide_this_line && do_hiding) {
- X /* do not print line? */
- X linenum--; /* compensate for linenum++ */
- X if (!in_header)
- X hide_this_line = FALSE;
- X }
- X#ifdef USETHREADS
- X else if (in_header) {
- X artline++;
- X linenum += tree_puts(art_buf,linenum+topline,0)-1;
- X }
- X#endif
- X else { /* just a normal line */
- X if (highlight==artline) { /* this line to be highlit? */
- X if (marking == STANDOUT) {
- X#ifdef NOFIREWORKS
- X if (erase_screen)
- X no_sofire();
- X#endif
- X standout();
- X }
- X else {
- X#ifdef NOFIREWORKS
- X if (erase_screen)
- X no_ulfire();
- X#endif
- X underline();
- X }
- X if (*bufptr == '\n')
- X putchar(' ');
- X }
- X#ifdef INNERSEARCH
- X outputok = !hide_everything;
- X /* get it into register, hopefully */
- X#endif
- X#ifdef CLEAREOL
- X#ifdef INNERSEARCH
- X if (outputok)
- X#endif
- X maybe_eol();
- X#endif /* CLEAREOL */
- X#ifdef CUSTOMLINES
- X if (pagestop && bufptr == art_buf &&
- X execute(&page_compex,art_buf) )
- X linenum = 32700;
- X#endif
- X for (outpos = 0; outpos < COLS; ) {
- X /* while line has room */
- X if (*(unsigned char *)bufptr >= ' ') { /* normal char? */
- X#ifdef ULSMARTS
- X if (*bufptr == '_') {
- X if (bufptr[1] == '\b') {
- X if (!under_lining && highlight!=artline
- X#ifdef INNERSEARCH
- X && outputok
- X#endif
- X ) {
- X under_lining++;
- X if (UG) {
- X if (bufptr != buf &&
- X bufptr[-1] == ' ') {
- X outpos--;
- X backspace();
- X }
- X }
- X underline();
- X }
- X bufptr += 2;
- X }
- X }
- X else {
- X if (under_lining) {
- X under_lining = 0;
- X un_underline();
- X if (UG) {
- X if (*bufptr == ' ')
- X goto skip_put;
- X outpos++;
- X }
- X }
- X }
- X#endif
- X#ifdef INNERSEARCH
- X if (outputok)
- X#endif
- X {
- X#ifdef ROTATION
- X if (rotate && !in_header
- X && isalpha(*bufptr)) {
- X if ((*bufptr & 31) <= 13)
- X putchar(*bufptr+13);
- X else
- X putchar(*bufptr-13);
- X }
- X else
- X#endif
- X putchar(*bufptr);
- X }
- X if (*UC && ((highlight==artline && marking == 1)
- X#ifdef ULSMARTS
- X || under_lining
- X#endif
- X )) {
- X backspace();
- X underchar();
- X }
- X skip_put:
- X bufptr++;
- X outpos++;
- X }
- X else if (*bufptr == '\n' || !*bufptr) {
- X /* newline? */
- X#ifdef ULSMARTS
- X if (under_lining) {
- X under_lining = 0;
- X un_underline();
- X }
- X#endif
- X#ifdef DEBUGGING
- X if (debug & DEB_INNERSRCH && outpos < COLS - 6) {
- X standout();
- X printf("%4d",artline);
- X un_standout();
- X }
- X#endif
- X#ifdef INNERSEARCH
- X if (outputok)
- X#endif
- X putchar('\n') FLUSH;
- X restart = 0;
- X outpos = 1000; /* signal normal \n */
- X }
- X else if (*bufptr == '\t') { /* tab? */
- X#ifdef INNERSEARCH
- X if (outputok)
- X#endif
- X putchar(*bufptr);
- X bufptr++;
- X outpos += 8 - outpos % 8;
- X }
- X else if (*bufptr == '\f') { /* form feed? */
- X#ifdef INNERSEARCH
- X if (outputok)
- X#endif
- X fputs("^L",stdout);
- X if (bufptr == blinebeg && highlight != artline)
- X linenum = 32700;
- X /* how is that for a magic number? */
- X bufptr++;
- X outpos += 2;
- X }
- X else { /* other control char */
- X#ifdef INNERSEARCH
- X if (outputok)
- X#endif
- X {
- X putchar('^');
- X if (highlight == artline && *UC && marking == 1) {
- X backspace();
- X underchar();
- X putchar(*bufptr+64);
- X backspace();
- X underchar();
- X }
- X else
- X putchar(*bufptr+64);
- X }
- X bufptr++;
- X outpos += 2;
- X }
- X
- X } /* end of column loop */
- X
- X if (outpos < 1000) {/* did line overflow? */
- X restart = bufptr;
- X /* restart here next time */
- X if (AM) { /* automatic margins on tty? */
- X if (!XN && *bufptr == '\n')
- X /* need we simulate XN? */
- X restart = 0;
- X /* skip the newline */
- X }
- X else { /* cursor just hangs there */
- X#ifdef INNERSEARCH
- X if (outputok)
- X#endif
- X putchar('\n') FLUSH;
- X /* so move it down ourselves */
- X if (*bufptr == '\n')
- X restart = 0;
- X /* simulate XN if need be */
- X }
- X#ifdef CLEAREOL
- X#ifdef INNERSEARCH
- X if (outputok)
- X#endif
- X {
- X /* force movement onto the new line so CE will work */
- X putchar(' ');
- X backspace();
- X maybe_eol();
- X }
- X#endif /* CLEAREOL */
- X }
- X
- X /* handle normal end of output line formalities */
- X
- X if (highlight == artline) {
- X /* were we highlighting line? */
- X if (marking == STANDOUT)
- X un_standout();
- X else
- X un_underline();
- X highlight = -1; /* no more we are */
- X }
- X artline++; /* count the line just printed */
- X if (artline - LINES + 1 > topline)
- X /* did we just scroll top line off? */
- X topline = artline - LINES + 1;
- X /* then recompute top line # */
- X }
- X
- X /* determine actual position in file */
- X
- X if (restart) /* stranded somewhere in the buffer? */
- X artpos += restart - blinebeg;
- X /* just calculate position */
- X else /* no, ftell will do */
- X artpos = ftell(artfp);
- X /* so do ftell */
- X vwtary(artline,artpos); /* remember pos in file */
- X } /* end of line loop */
- X
- X#ifdef INNERSEARCH
- X innersearch = 0;
- X if (hide_everything) {
- X hide_everything = FALSE;
- X *buf = Ctl('l');
- X goto fake_command;
- X }
- X#endif
- X if (linenum >= 32700)/* did last line have formfeed? */
- X vwtary(artline-1,-vrdary(artline-1));
- X /* remember by negating pos in file */
- X
- X special = FALSE; /* end of page, so reset page length */
- X firstpage = FALSE; /* and say it is not 1st time thru */
- X
- X /* extra loop bombout */
- X
- X if (artpos == artsize) {/* did we just now reach EOF? */
- X mode = oldmode;
- X return DA_NORM; /* avoid --MORE--(100%) */
- X }
- X
- X/* not done with this article, so pretend we are a pager */
- X
- Xreask_pager:
- X unflush_output(); /* disable any ^O in effect */
- X standout(); /* enter standout mode */
- X printf("--MORE--(%ld%%)",(long)(artpos*100/artsize));
- X un_standout(); /* leave standout mode */
- X#ifdef CLEAREOL
- X maybe_eol();
- X#endif
- X fflush(stdout);
- X/* reinp_pager: /* unused, commented for lint */
- X eat_typeahead();
- X#ifdef DEBUGGING
- X if (debug & DEB_CHECKPOINTING) {
- X printf("(%d %d %d)",checkcount,linenum,artline);
- X fflush(stdout);
- X }
- X#endif
- X if (checkcount >= docheckwhen &&
- X linenum == LINES &&
- X (artline > 40 || checkcount >= docheckwhen+10) ) {
- X /* while he is reading a whole page */
- X /* in an article he is interested in */
- X checkcount = 0;
- X checkpoint_rc(); /* update .newsrc */
- X }
- X collect_subjects(); /* loads subject cache until */
- X /* input is pending */
- X mode = 'p';
- X getcmd(buf);
- X if (errno) {
- X if (LINES < 100 && !int_count)
- X *buf = '\f';/* on CONT fake up refresh */
- X else {
- X *buf = 'q'; /* on INTR or paper just quit */
- X }
- X }
- X carriage_return();
- X#ifndef CLEAREOL
- X erase_eol(); /* and erase the prompt */
- X#else
- X if (erase_screen && can_home_clear)
- X clear_rest();
- X else
- X erase_eol(); /* and erase the prompt */
- X#endif /* CLEAREOL */
- X carriage_return(); /* Resets kernel's tab column counter to 0 */
- X fflush(stdout);
- X
- X fake_command: /* used by innersearch */
- X
- X /* parse and process pager command */
- X
- X switch (page_switch()) {
- X case PS_ASK: /* reprompt "--MORE--..." */
- X goto reask_pager;
- X case PS_RAISE: /* reparse on article level */
- X mode = oldmode;
- X return DA_RAISE;
- X case PS_TOEND: /* fast pager loop exit */
- X mode = oldmode;
- X return DA_TOEND;
- X case PS_NORM: /* display more article */
- X break;
- X }
- X } /* end of page loop */
- X}
- X
- X/* process pager commands */
- X
- Xint
- Xpage_switch()
- X{
- X register char *s;
- X
- X switch (*buf) {
- X case 'd':
- X case Ctl('d'): /* half page */
- X special = TRUE;
- X slines = LINES / 2 + 1;
- X if (marking && *blinebeg != '\f'
- X#ifdef CUSTOMLINES
- X && (!pagestop || blinebeg != art_buf ||
- X !execute(&page_compex,blinebeg))
- X#endif
- X ) {
- X up_line();
- X highlight = --artline;
- X restart = blinebeg;
- X artpos = alinebeg;
- X }
- X return PS_NORM;
- X case '!': /* shell escape */
- X escapade();
- X return PS_ASK;
- X#ifdef INNERSEARCH
- X case Ctl('i'):
- X gline = 3;
- X sprintf(cmd_buf,"^[^%c]",*blinebeg);
- X compile(&gcompex,cmd_buf,TRUE,TRUE);
- X goto caseG;
- X case Ctl('g'):
- X gline = 3;
- X compile(&gcompex,"^Subject:",TRUE,TRUE);
- X goto caseG;
- X case 'g': /* in-article search */
- X if (!finish_command(FALSE))/* get rest of command */
- X return PS_ASK;
- X s = buf+1;
- X if (isspace(*s))
- X s++;
- X if ((s = compile(&gcompex,s,TRUE,TRUE)) != Nullch) {
- X /* compile regular expression */
- X printf("\n%s\n",s) FLUSH;
- X return PS_ASK;
- X }
- X carriage_return();
- X erase_eol(); /* erase the prompt */
- X carriage_return(); /* Resets kernel's tab column counter to 0 */
- X /* FALL THROUGH */
- X caseG:
- X case 'G': {
- X /* ART_LINE lines_to_skip = 0; */
- X ART_POS start_where;
- X
- X if (gline < 0 || gline > LINES-2)
- X gline = LINES-2;
- X#ifdef DEBUGGING
- X if (debug & DEB_INNERSRCH)
- X printf("Start here? %d >=? %d\n",topline + gline + 1,artline)
- X FLUSH;
- X#endif
- X if (*buf == Ctl('i') || topline+gline+1 >= artline)
- X start_where = artpos;
- X /* in case we had a line wrap */
- X else {
- X start_where = vrdary(topline+gline+1);
- X if (start_where < 0)
- X start_where = -start_where;
- X }
- X if (start_where < htype[PAST_HEADER].ht_minpos)
- X start_where = htype[PAST_HEADER].ht_minpos;
- X fseek(artfp,(long)start_where,0);
- X innersearch = 0; /* assume not found */
- X while (fgets(buf, sizeof buf, artfp) != Nullch) {
- X /* lines_to_skip++; NOT USED NOW */
- X#ifdef DEBUGGING
- X if (debug & DEB_INNERSRCH)
- X printf("Test %s",buf) FLUSH;
- X#endif
- X if (execute(&gcompex,buf) != Nullch) {
- X innersearch = ftell(artfp);
- X break;
- X }
- X }
- X if (!innersearch) {
- X fseek(artfp,artpos,0);
- X fputs("(Not found)",stdout) FLUSH;
- X return PS_ASK;
- X }
- X#ifdef DEBUGGING
- X if (debug & DEB_INNERSRCH)
- X printf("On page? %ld <=? %ld\n",(long)innersearch,(long)artpos)
- X FLUSH;
- X#endif
- X if (innersearch <= artpos) { /* already on page? */
- X if (innersearch < artpos) {
- X artline = topline+1;
- X while (vrdary(artline) < innersearch)
- X artline++;
- X }
- X highlight = artline - 1;
- X#ifdef DEBUGGING
- X if (debug & DEB_INNERSRCH)
- X printf("@ %d\n",highlight) FLUSH;
- X#endif
- X topline = highlight - gline;
- X if (topline < -1)
- X topline = -1;
- X *buf = '\f'; /* fake up a refresh */
- X innersearch = 0;
- X return page_switch();
- X }
- X else { /* who knows how many lines it is? */
- X do_fseek = TRUE;
- X hide_everything = TRUE;
- X }
- X return PS_NORM;
- X }
- X#else
- X case 'g': case 'G': case Ctl('g'):
- X notincl("g");
- X return PS_ASK;
- X#endif
- X case '\n': /* one line */
- X special = TRUE;
- X slines = 2;
- X return PS_NORM;
- X#ifdef ROTATION
- X case 'X':
- X rotate = !rotate;
- X /* FALL THROUGH */
- X#endif
- X case 'l':
- X case '\f': /* refresh screen */
- X#ifdef DEBUGGING
- X if (debug & DEB_INNERSRCH) {
- X printf("Topline = %d",topline) FLUSH;
- X gets(buf);
- X }
- X#endif
- X clear();
- X carriage_return(); /* Resets kernel's tab column counter to 0 */
- X do_fseek = TRUE;
- X artline = topline;
- X if (artline < 0)
- X artline = 0;
- X firstpage = (topline < 0);
- X return PS_NORM;
- X case 'b':
- X case '\b':
- X case Ctl('b'): { /* back up a page */
- X ART_LINE target;
- X
- X#ifndef CLEAREOL
- X clear();
- X#else
- X if (can_home_clear) /* if we can home do it */
- X home_cursor();
- X else
- X clear();
- X
- X#endif /* CLEAREOL */
- X carriage_return(); /* Resets kernel's tab column counter to 0 */
- X do_fseek = TRUE; /* reposition article file */
- X target = topline - (LINES - 2);
- X artline = topline;
- X if (artline >= 0) do {
- X artline--;
- X } while(artline >= 0 && artline > target && vrdary(artline-1) >= 0);
- X topline = artline;
- X /* remember top line of screen */
- X /* (line # within article file) */
- X if (artline < 0)
- X artline = 0;
- X firstpage = (topline < 0);
- X return PS_NORM;
- X }
- X case 'h': { /* help */
- X int cmd;
- X
- X if ((cmd = help_page()) > 0)
- X pushchar(cmd);
- X return PS_ASK;
- X }
- X#ifdef USETHREADS
- X case 't': /* output thread data */
- X page_line = 1;
- X p_art = curr_p_art;
- X entire_tree();
- X return PS_ASK;
- X#endif
- X case '\177':
- X case '\0': /* treat del,break as 'n' */
- X *buf = 'n';
- X /* FALL THROUGH */
- X case 'k': case 'K':
- X#ifdef USETHREADS
- X case 'T': case 'J':
- X#endif
- X case 'n': case 'N': case Ctl('n'):
- X case 's': case 'S':
- X case 'e':
- X case 'u':
- X case 'w': case 'W':
- X case '|':
- X mark_as_read(); /* mark article as read */
- X /* FALL THROUGH */
- X#ifdef USETHREADS
- X case 'U': case ',':
- X case '<': case '>':
- X case '[': case ']':
- X case '{': case '}':
- X case '+': case ':':
- X#endif
- X case '#':
- X case '$':
- X case '&':
- X case '-':
- X case '.':
- X case '/':
- X case '1': case '2': case '3': case '4': case '5':
- X case '6': case '7': case '8': case '9':
- X case '=':
- X case '?':
- X case 'c': case 'C':
- X#ifdef DEBUGGING
- X case 'D':
- X#endif
- X case 'E':
- X case 'f': case 'F':
- X case 'j':
- X case Ctl('k'):
- X case 'm': case 'M':
- X case 'p': case 'P': case Ctl('p'):
- X case 'Q':
- X case 'r': case 'R': case Ctl('r'):
- X case 'v':
- X case 'Y':
- X#ifndef ROTATION
- X case 'x': case 'X':
- X#endif
- X case Ctl('x'):
- X case '^':
- X
- X#ifdef ROTATION
- X rotate = FALSE;
- X#endif
- X reread = FALSE;
- X do_hiding = TRUE;
- X if (index("nNpP\016\018",*buf) == Nullch &&
- X index("wWsSe:!&|/?123456789.",*buf) != Nullch) {
- X setdfltcmd();
- X standout(); /* enter standout mode */
- X printf(prompt,mailcall,dfltcmd);
- X /* print prompt, whatever it is */
- X un_standout(); /* leave standout mode */
- X putchar(' ');
- X fflush(stdout);
- X }
- X return PS_RAISE; /* and pretend we were at end */
- X#ifdef ROTATION
- X case 'x':
- X rotate = TRUE;
- X /* FALL THROUGH */
- X#endif
- X case 'y':
- X case Ctl('v'):
- X /* Leaving it undocumented in case */
- X /* I want to steal the key--LAW */
- X case ' ': /* continue current article */
- X if (erase_screen) { /* -e? */
- X#ifndef CLEAREOL
- X clear(); /* clear screen */
- X#else
- X if (can_home_clear) /* if we can home do it */
- X home_cursor();
- X else
- X clear(); /* else clear screen */
- X
- X#endif /* CLEAREOL */
- X carriage_return(); /* Resets kernel's tab column counter to 0 */
- X fflush(stdout);
- X
- X if (*blinebeg != '\f'
- X#ifdef CUSTOMLINES
- X && (!pagestop || blinebeg != art_buf ||
- X !execute(&page_compex,blinebeg))
- X#endif
- X ) {
- X restart = blinebeg;
- X artline--; /* restart this line */
- X artpos = alinebeg;
- X if (marking) /* and mark repeated line */
- X highlight = artline;
- X }
- X topline = artline;
- X /* and remember top line of screen */
- X /* (line # within article file) */
- X }
- X else if (marking && *blinebeg != '\f'
- X#ifdef CUSTOMLINES
- X && (!pagestop || blinebeg != art_buf ||
- X !execute(&page_compex,blinebeg))
- X#endif
- X ) {
- X /* are we marking repeats? */
- X up_line(); /* go up one line */
- X highlight = --artline;/* and get ready to highlight */
- X restart = blinebeg; /* the old line */
- X artpos = alinebeg;
- X }
- X return PS_NORM;
- X case 'q': /* quit this article? */
- X do_hiding = TRUE;
- X return PS_TOEND;
- X default:
- X fputs(hforhelp,stdout) FLUSH;
- X settle_down();
- X return PS_ASK;
- X }
- X}
- X
- X#ifdef INNERSEARCH
- Xbool
- Xinnermore()
- X{
- X if (artpos < innersearch) { /* not even on page yet? */
- X#ifdef DEBUGGING
- X if (debug & DEB_INNERSRCH)
- X printf("Not on page %ld < %ld\n",(long)artpos,(long)innersearch)
- X FLUSH;
- X#endif
- X return TRUE;
- X }
- X if (artpos == innersearch) { /* just got onto page? */
- X isrchline = artline; /* remember first line after */
- X highlight = artline - 1;
- X#ifdef DEBUGGING
- X if (debug & DEB_INNERSRCH)
- X printf("There it is %ld = %ld, %d @ %d\n",(long)artpos,
- X (long)innersearch,hide_everything,highlight) FLUSH;
- X#endif
- X if (hide_everything) { /* forced refresh? */
- X topline = highlight - gline;
- X if (topline < -1)
- X topline = -1;
- X return FALSE; /* let refresh do it all */
- X }
- X }
- X#ifdef DEBUGGING
- X if (debug & DEB_INNERSRCH)
- X printf("Not far enough? %d <? %d + %d\n",artline,isrchline,gline)
- X FLUSH;
- X#endif
- X if (artline < isrchline + gline) {
- X return TRUE;
- X }
- X return FALSE;
- X}
- X#endif
- END_OF_FILE
- if test 26201 -ne `wc -c <'art.c'`; then
- echo shar: \"'art.c'\" unpacked with wrong size!
- fi
- # end of 'art.c'
- fi
- if test -f 'ng.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'ng.c'\"
- else
- echo shar: Extracting \"'ng.c'\" \(34884 characters\)
- sed "s/^X//" >'ng.c' <<'END_OF_FILE'
- X/* $Header: ng.c,v 4.3.3.3 91/01/16 03:18:16 davison Trn $
- X *
- X * $Log: ng.c,v $
- X * Revision 4.3.3.3 91/01/16 03:18:16 davison
- X * Integrated rn patches 48-54. Fixed in_char/verify interaction.
- X *
- X * Revision 4.3.3.2 90/08/20 16:03:45 davison
- X * Fixed bug in backpage code.
- X *
- X * Revision 4.3.3.1 90/07/21 20:27:17 davison
- X * Initial Trn Release
- X *
- X * Revision 4.3.2.9 91/01/05 14:56:47 sob
- X * Removed bogus "fast skip" for NNTP.
- X *
- X * Revision 4.3.2.8 90/11/22 16:14:17 sob
- X * Added changes to accomodate picky C preprocessors
- X *
- X * Revision 4.3.2.7 90/04/21 14:44:23 sob
- X * Revised previous patch insure that it does not decrement below zero.
- X *
- X * Revision 4.3.2.6 90/03/22 23:04:49 sob
- X * Fixes provided by Wayne Davison <drivax!davison>
- X *
- X * Revision 4.3.2.5 89/12/09 01:18:42 sob
- X * Fixed a bad call to nntpopen().
- X *
- X * Revision 4.3.2.4 89/11/28 01:51:20 sob
- X * Removed redundant #include directive.
- X *
- X * Revision 4.3.2.3 89/11/27 01:31:03 sob
- X * Altered NNTP code per ideas suggested by Bela Lubkin
- X * <filbo@gorn.santa-cruz.ca.us>
- X *
- X * Revision 4.3.2.2 89/11/26 22:53:35 sob
- X * Add new patches to make RRN be faster.
- X *
- X * Revision 4.3.2.1 89/11/06 00:54:27 sob
- X * Added RRN support from NNTP 1.5
- X *
- X * Revision 4.3.1.6 85/09/10 11:03:42 lwall
- X * Improved %m in in_char().
- X *
- X * Revision 4.3.1.5 85/09/05 12:34:37 lwall
- X * Catchup command could make unread article count too big.
- X *
- X * Revision 4.3.1.4 85/07/23 18:19:46 lwall
- X * Added MAILCALL environment variable.
- X *
- X * Revision 4.3.1.3 85/05/16 16:48:09 lwall
- X * Fixed unsubsubscribe.
- X *
- X * Revision 4.3.1.2 85/05/13 09:29:28 lwall
- X * Added CUSTOMLINES option.
- X *
- X * Revision 4.3.1.1 85/05/10 11:36:00 lwall
- X * Branch for patches.
- X *
- X * Revision 4.3 85/05/01 11:43:43 lwall
- X * Baseline for release with 4.3bsd.
- X *
- X */
- X
- X#include "EXTERN.h"
- X#include "common.h"
- X#include "rn.h"
- X#include "term.h"
- X#include "final.h"
- X#include "util.h"
- X#include "artsrch.h"
- X#include "cheat.h"
- X#include "help.h"
- X#include "kfile.h"
- X#include "rcstuff.h"
- X#include "head.h"
- X#include "bits.h"
- X#include "art.h"
- X#include "artio.h"
- X#include "ngstuff.h"
- X#include "intrp.h"
- X#include "respond.h"
- X#include "ngdata.h"
- X#include "backpage.h"
- X#include "rcln.h"
- X#include "last.h"
- X#include "search.h"
- X#ifdef SERVER
- X#include "server.h"
- X#endif
- X#ifdef USETHREADS
- X#include "rthreads.h"
- X#endif
- X#include "uudecode.h"
- X#include "INTERN.h"
- X#include "ng.h"
- X#include "artstate.h" /* somebody has to do it */
- X
- X/* art_switch() return values */
- X
- X#define AS_NORM 0
- X#define AS_INP 1
- X#define AS_ASK 2
- X#define AS_CLEAN 3
- X
- XART_NUM recent_art = -1; /* previous article # for '-' command */
- XART_NUM curr_art = -1; /* current article # */
- Xint exit_code = NG_NORM;
- X
- Xvoid
- Xng_init()
- X{
- X
- X#ifdef KILLFILES
- X open_kfile(KF_GLOBAL);
- X#endif
- X#ifdef CUSTOMLINES
- X init_compex(&hide_compex);
- X init_compex(&page_compex);
- X#endif
- X}
- X
- X/* do newsgroup on line ng with name ngname */
- X
- X/* assumes that we are chdir'ed to SPOOL, and assures that that is
- X * still true upon return, but chdirs to SPOOL/ngname in between
- X *
- X * If you can understand this routine, you understand most of the program.
- X * The basic structure is:
- X * for each desired article
- X * for each desired page
- X * for each line on page
- X * if we need another line from file
- X * get it
- X * if it's a header line
- X * do special things
- X * for each column on page
- X * put out a character
- X * end loop
- X * end loop
- X * end loop
- X * end loop
- X *
- X * (Actually, the pager is in another routine.)
- X *
- X * The chief problem is deciding what is meant by "desired". Most of
- X * the messiness of this routine is due to the fact that people want
- X * to do unstructured things all the time. I have used a few judicious
- X * goto's where I thought it improved readability. The rest of the messiness
- X * arises from trying to be both space and time efficient. Have fun.
- X */
- X
- Xint
- Xdo_newsgroup(start_command)
- Xchar *start_command; /* command to fake up first */
- X{
- X#ifdef SERVER
- X char ser_line[256];
- X char artname[32];
- X static long our_pid=0;
- X#endif /* SERVER */
- X char oldmode = mode;
- X register long i; /* scratch */
- X int skipstate; /* how many unavailable articles */
- X /* have we skipped already? */
- X
- X char *whatnext = "%sWhat next? [%s]";
- X
- X#ifdef SERVER
- X if (our_pid == 0) /* Agreed, this is gross */
- X our_pid = getpid();
- X#endif /* SERVER */
- X
- X#ifdef ARTSEARCH
- X srchahead = (scanon && ((ART_NUM)toread[ng]) >= scanon ? -1 : 0);
- X /* did they say -S? */
- X#endif
- X
- X mode = 'a';
- X#ifdef USETHREADS
- X recent_p_art = curr_p_art = Nullart;
- X#endif
- X recent_art = curr_art = -1;
- X exit_code = NG_NORM;
- X
- X#ifdef SERVER
- X sprintf(ser_line, "GROUP %s", ngname);
- X put_server(ser_line);
- X if (get_server(ser_line, sizeof(ser_line)) < 0) {
- X fprintf(stderr, "rrn: Unexpected close of server socket.\n");
- X finalize(1);
- X }
- X if (*ser_line != CHAR_OK) {
- X if (atoi(ser_line) != ERR_NOGROUP)
- X fprintf(stderr, "rrn: server response to GROUP %s:\n%s\n",
- X ngname, ser_line);
- X return (-1);
- X }
- X#else /* not SERVER */
- X if (eaccess(ngdir,5)) { /* directory read protected? */
- X if (eaccess(ngdir,0)) {
- X#ifdef VERBOSE
- X IF(verbose)
- X printf("\nNewsgroup %s does not have a spool directory!\n",
- X ngname) FLUSH;
- X ELSE
- X#endif
- X#ifdef TERSE
- X printf("\nNo spool for %s!\n",ngname) FLUSH;
- X#endif
- X#ifdef CATCHUP
- X catch_up(ng);
- X#endif
- X toread[ng] = TR_NONE;
- X }
- X else {
- X#ifdef VERBOSE
- X IF(verbose)
- X printf("\nNewsgroup %s is not currently accessible.\n",
- X ngname) FLUSH;
- X ELSE
- X#endif
- X#ifdef TERSE
- X printf("\n%s not readable.\n",ngname) FLUSH;
- X#endif
- X toread[ng] = TR_NONE; /* make this newsgroup invisible */
- X /* (temporarily) */
- X }
- X mode = oldmode;
- X return -1;
- X }
- X
- X /* chdir to newsgroup subdirectory */
- X
- X if (chdir(ngdir)) {
- X printf(nocd,ngdir) FLUSH;
- X mode = oldmode;
- X return -1;
- X }
- X#endif /* SERVER */
- X
- X#ifdef CACHESUBJ
- X subj_list = Null(char **); /* no subject list till needed */
- X#endif
- X
- X /* initialize control bitmap */
- X
- X if (initctl()) {
- X mode = oldmode;
- X return -1;
- X }
- X
- X /* FROM HERE ON, RETURN THRU CLEANUP OR WE ARE SCREWED */
- X
- X /* grab threaded data */
- X
- X#ifdef USETHREADS
- X if (ThreadedGroup && (ThreadedGroup = use_data(thread_name(ngname)))) {
- X /* check if thread file is newer than the active2 entry (this is
- X ** possible when mthreads is still running.) */
- X if (total.last > lastart) {
- X grow_ctl(total.last); /* sets lastart */
- X }
- X else if (total.last < lastart) {
- X /* If the active2 entry is newer than the data file, something
- X ** bad is going on. Forget using the thread data. */
- X unuse_data(0);
- X ThreadedGroup = FALSE;
- X }
- X }
- X#endif
- X
- X in_ng = TRUE; /* tell the world we are here */
- X forcelast = TRUE; /* if 0 unread, do not bomb out */
- X
- X /* remember what newsgroup we were in for sake of posterity */
- X
- X writelast();
- X
- X /* see if there are any special searches to do */
- X
- X#ifdef KILLFILES
- X open_kfile(KF_LOCAL);
- X#ifdef VERBOSE
- X IF(verbose)
- X kill_unwanted(firstart,"Looking for articles to kill...\n\n",TRUE);
- X ELSE
- X#endif
- X#ifdef TERSE
- X kill_unwanted(firstart,"Killing...\n\n",TRUE);
- X#endif
- X#endif
- X#ifdef USETHREADS
- X first_art();
- X#else
- X art=firstart;
- X#endif
- X
- X /* do they want a special top line? */
- X
- X firstline = getval("FIRSTLINE",Nullch);
- X
- X /* custom line suppression, custom page ending */
- X
- X#ifdef CUSTOMLINES
- X if (hideline = getval("HIDELINE",Nullch))
- X compile(&hide_compex,hideline,TRUE,TRUE);
- X if (pagestop = getval("PAGESTOP",Nullch))
- X compile(&page_compex,pagestop,TRUE,TRUE);
- X#endif
- X
- X /* now read each unread article */
- X
- X rc_changed = doing_ng = TRUE; /* enter the twilight zone */
- X skipstate = 0; /* we have not skipped anything (yet) */
- X checkcount = 0; /* do not checkpoint for a while */
- X do_fseek = FALSE; /* start 1st article at top */
- X if (art > lastart)
- X#ifdef USETHREADS
- X first_art();
- X#else
- X art=firstart; /* init the for loop below */
- X#endif
- X for (; art<=lastart+1; ) { /* for each article */
- X
- X /* do we need to "grow" the newsgroup? */
- X
- X#ifdef USETHREADS
- X if (ThreadedGroup) {
- X if ((art > lastart || forcegrow) && getngsize(ng) > total.last) {
- X unuse_data(1); /* free data with selections saved */
- X if ((ThreadedGroup = use_data(thread_name(ngname))) != 0) {
- X grow_ctl(total.last); /* sets lastart */
- X find_article(art);
- X curr_p_art = p_art;
- X }
- X forcegrow = FALSE;
- X }
- X }
- X else
- X#endif
- X if (art > lastart || forcegrow)
- X grow_ctl(getngsize(ng));
- X check_first(art); /* make sure firstart is still 1st */
- X if (start_command) { /* fake up an initial command? */
- X prompt = whatnext;
- X strcpy(buf,start_command);
- X free(start_command);
- X start_command = Nullch;
- X#ifdef USETHREADS
- X p_art = Nullart;
- X#endif
- X art = lastart+1;
- X goto article_level;
- X }
- X if (art>lastart) { /* are we off the end still? */
- X ART_NUM ucount = 0; /* count of unread articles left */
- X
- X for (i=firstart; i<=lastart; i++)
- X if (!(ctl_read(i)))
- X ucount++; /* count the unread articles */
- X#ifdef DEBUGGING
- X /*NOSTRICT*/
- X if (debug && ((ART_NUM)toread[ng]) != ucount)
- X printf("(toread=%ld sb %ld)",(long)toread[ng],(long)ucount)
- X FLUSH;
- X#endif
- X /*NOSTRICT*/
- X toread[ng] = (ART_UNREAD)ucount; /* this is perhaps pointless */
- X art = lastart + 1; /* keep bitmap references sane */
- X if (art != curr_art) {
- X#ifdef USETHREADS
- X recent_p_art = curr_p_art;
- X find_article(art);
- X curr_p_art = p_art;
- X#endif
- X recent_art = curr_art;
- X /* remember last article # (for '-') */
- X curr_art = art; /* remember this article # */
- X }
- X if (erase_screen)
- X clear(); /* clear the screen */
- X else
- X fputs("\n\n",stdout) FLUSH;
- X#ifdef VERBOSE
- X IF(verbose)
- X printf("End of newsgroup %s.",ngname);
- X /* print pseudo-article */
- X ELSE
- X#endif
- X#ifdef TERSE
- X printf("End of %s",ngname);
- X#endif
- X#ifdef USETHREADS
- X if (ThreadedGroup)
- X ucount -= unthreaded;
- X#endif
- X if (ucount) {
- X#ifdef USETHREADS
- X if (selected_root_cnt)
- X printf(" (%ld + %ld articles still unread)",
- X (long)selected_count,(long)ucount-selected_count);
- X else
- X#endif
- X printf(" (%ld article%s still unread)",
- X (long)ucount,ucount==1?nullstr:"s");
- X }
- X else {
- X if (!forcelast)
- X goto cleanup; /* actually exit newsgroup */
- X }
- X prompt = whatnext;
- X#ifdef ARTSEARCH
- X srchahead = 0; /* no more subject search mode */
- X#endif
- X fputs("\n\n",stdout) FLUSH;
- X skipstate = 0; /* back to none skipped */
- X }
- X else if (!reread && was_read(art)) {
- X /* has this article been read? */
- X#ifdef USETHREADS
- X follow_thread('n');
- X#else
- X art++; /* then skip it */
- X#endif
- X continue;
- X }
- X else if
- X (!reread && !was_read(art)
- X#ifdef SERVER
- X && nntpopen(art,GET_HEADER) == Nullfp) {
- X#else
- X && artopen(art) == Nullfp) { /* never read it, & cannot find it? */
- X if (errno != ENOENT) { /* has it not been deleted? */
- X#ifdef VERBOSE
- X IF(verbose)
- X printf("\n(Article %ld exists but is unreadable.)\n",
- X (long)art) FLUSH;
- X ELSE
- X#endif
- X#ifdef TERSE
- X printf("\n(%ld unreadable.)\n",(long)art) FLUSH;
- X#endif
- X skipstate = 0;
- X sleep(2);
- X }
- X#endif
- X switch(skipstate++) {
- X case 0:
- X clear();
- X#ifdef VERBOSE
- X IF(verbose)
- X fputs("Skipping unavailable article",stdout);
- X ELSE
- X#endif
- X#ifdef TERSE
- X fputs("Skipping",stdout);
- X#endif
- X pad(just_a_sec/3);
- X sleep(1);
- X break;
- X case 1:
- X fputs("..",stdout);
- X fflush(stdout);
- X break;
- X default:
- X putchar('.');
- X fflush(stdout);
- X#ifndef SERVER
- X#define READDIR
- X#ifdef READDIR
- X { /* fast skip patch */
- X ART_NUM newart;
- X
- X if (! (newart=getngmin(".",art)))
- X newart = lastart+1;
- X for (i=art; i<newart; i++)
- X oneless(i);
- X art = newart - 1;
- X }
- X#endif /* READDIR */
- X#endif /* SERVER */
- X break;
- X }
- X oneless(art); /* mark deleted as read */
- X#ifdef USETHREADS
- X count_roots(FALSE); /* Keep selected_count accurate */
- X find_article(art);
- X follow_thread('n');
- X#else
- X art++; /* try next article */
- X#endif
- X continue;
- X }
- X else { /* we have a real live article */
- X skipstate = 0; /* back to none skipped */
- X if (art != curr_art) {
- X#ifdef USETHREADS
- X recent_p_art = curr_p_art;
- X find_article(art);
- X curr_p_art = p_art;
- X#endif
- X recent_art = curr_art;
- X /* remember last article # (for '-') */
- X curr_art = art; /* remember this article # */
- X }
- X if (!do_fseek) { /* starting at top of article? */
- X artline = 0; /* start at the beginning */
- X topline = -1; /* and remember top line of screen */
- X /* (line # within article file) */
- X }
- X clear(); /* clear screen */
- X if (!artopen(art)) { /* make sure article is found & open */
- X#ifdef USETHREADS
- X char tmpbuf[256];
- X /* see if we have tree data for this article anyway */
- X init_tree();
- X sprintf(tmpbuf,"%s #%ld is not available.",ngname,(long)art);
- X tree_puts(tmpbuf,0,0);
- X vwtary((ART_LINE)0,(ART_POS)0);
- X finish_tree(1);
- X prompt = whatnext;
- X#else
- X printf("Article %ld of %s is not available.\n\n",
- X (long)art,ngname) FLUSH;
- X prompt = whatnext;
- X#endif
- X#ifdef ARTSEARCH
- X srchahead = 0;
- X#endif
- X }
- X else { /* found it, so print it */
- X switch (do_article()) {
- X case DA_CLEAN: /* quit newsgroup */
- X goto cleanup;
- X case DA_TOEND: /* do not mark as read */
- X goto reask_article;
- X case DA_RAISE: /* reparse command at end of art */
- X goto article_level;
- X case DA_NORM: /* normal end of article */
- X break;
- X }
- X }
- X if (art >= absfirst) /* don't mark non-existant articles */
- X mark_as_read(); /* mark current article as read */
- X reread = FALSE;
- X do_hiding = TRUE;
- X#ifdef ROTATION
- X rotate = FALSE;
- X#endif
- X }
- X
- X/* if these gotos bother you, think of this as a little state machine */
- X
- Xreask_article:
- X#ifdef MAILCALL
- X setmail();
- X#endif
- X setdfltcmd();
- X#ifdef CLEAREOL
- X if (erase_screen && can_home_clear)
- X clear_rest();
- X#endif /* CLEAREOL */
- X unflush_output(); /* disable any ^O in effect */
- X standout(); /* enter standout mode */
- X printf(prompt,mailcall,dfltcmd);/* print prompt, whatever it is */
- X un_standout(); /* leave standout mode */
- X putchar(' ');
- X fflush(stdout);
- Xreinp_article:
- X eat_typeahead();
- X#ifdef PENDING
- X look_ahead(); /* see what we can do in advance */
- X if (!input_pending())
- X collect_subjects(); /* loads subject cache until */
- X /* input is pending */
- X#endif
- X getcmd(buf);
- X if (errno || *buf == '\f') {
- X if (LINES < 100 && !int_count)
- X *buf = '\f'; /* on CONT fake up refresh */
- X else {
- X putchar('\n') FLUSH; /* but only on a crt */
- X goto reask_article;
- X }
- X }
- Xarticle_level:
- X
- X /* parse and process article level command */
- X
- X switch (art_switch()) {
- X case AS_INP: /* multichar command rubbed out */
- X goto reinp_article;
- X case AS_ASK: /* reprompt "End of article..." */
- X goto reask_article;
- X case AS_CLEAN: /* exit newsgroup */
- X goto cleanup;
- X case AS_NORM: /* display article art */
- X break;
- X }
- X } /* end of article selection loop */
- X
- X/* shut down newsgroup */
- X
- Xcleanup:
- X uud_end();
- X#ifdef KILLFILES
- X kill_unwanted(firstart,"\nCleaning up...\n\n",FALSE);
- X /* do cleanup from KILL file, if any */
- X#endif
- X#ifdef USETHREADS
- X if (ThreadedGroup)
- X unuse_data(0); /* free article thread data */
- X#endif
- X in_ng = FALSE; /* leave newsgroup state */
- X if (artfp != Nullfp) { /* article still open? */
- X fclose(artfp); /* close it */
- X artfp = Nullfp; /* and tell the world */
- X#ifdef SERVER
- X sprintf(artname, "/tmp/rrn%ld.%ld", (long) openart, our_pid);
- X UNLINK(artname);
- X#endif /* SERVER */
- X openart = 0;
- X }
- X putchar('\n') FLUSH;
- X yankback(); /* do a Y command */
- X restore_ng(); /* reconstitute .newsrc line */
- X doing_ng = FALSE; /* tell sig_catcher to cool it */
- X free(ctlarea); /* return the control area */
- X#ifdef CACHESUBJ
- X if (subj_list) {
- X for (i=OFFSET(lastart); i>=0; --i)
- X if (subj_list[i])
- X free(subj_list[i]);
- X#ifndef lint
- X free((char*)subj_list);
- X#endif /* lint */
- X }
- X#endif
- X write_rc(); /* and update .newsrc */
- X rc_changed = FALSE; /* tell sig_catcher it is ok */
- X if (chdir(spool)) {
- X printf(nocd,spool) FLUSH;
- X sig_catcher(0);
- X }
- X#ifdef KILLFILES
- X if (localkfp) {
- X fclose(localkfp);
- X localkfp = Nullfp;
- X }
- X#endif
- X mode = oldmode;
- X return exit_code;
- X} /* Whew! */
- X
- X/* decide what to do at the end of an article */
- X
- Xint
- Xart_switch()
- X{
- X register ART_NUM i;
- X
- X setdef(buf,dfltcmd);
- X#ifdef VERIFY
- X printcmd();
- X#endif
- X
- X switch (*buf) {
- X#ifdef USETHREADS
- X case '<': /* goto previous thread */
- X if (!ThreadedGroup) {
- X goto group_unthreaded;
- X }
- X prev_root();
- X return AS_NORM;
- X case '>': /* goto next thread */
- X if (!ThreadedGroup) {
- X goto group_unthreaded;
- X }
- X next_root();
- X return AS_NORM;
- X case 'U': { /* unread some articles */
- X char *u_prompt, *u_help_thread;
- X
- X if (!ThreadedGroup) {
- X dfltcmd = "a";
- X u_help_thread = nullstr;
- X#ifdef VERBOSE
- X IF(verbose)
- X u_prompt = "\nSet unread: all articles? [an] ";
- X ELSE
- X#endif
- X#ifdef TERSE
- X u_prompt = "\nUnread? [an] ";
- X#endif
- X }
- X else if (!p_art || art > lastart) {
- X dfltcmd = "+";
- X u_help_thread = nullstr;
- X#ifdef VERBOSE
- X IF(verbose)
- X u_prompt = "\nSet unread: +select or all? [+an] ";
- X ELSE
- X#endif
- X#ifdef TERSE
- X u_prompt = "\nUnread? [+an] ";
- X#endif
- X }
- X else {
- X dfltcmd = "t";
- X#ifdef VERBOSE
- X IF(verbose) {
- X u_prompt = "\n\
- XSet unread: thread, subthread, +select, or all? [ts+an] ";
- X u_help_thread = "\
- XType t or SP to mark this thread's articles as unread.\n\
- XType s to mark the current article and its descendants as unread.\n";
- X }
- X ELSE
- X#endif
- X#ifdef TERSE
- X {
- X u_prompt = "\nUnread? [ts+an] ";
- X u_help_thread = "\
- Xt or SP to mark thread unread.\n\
- Xs to mark subthread unread.\n";
- X }
- X#endif
- X }
- X reask_unread:
- X in_char(u_prompt,'u');
- X setdef(buf,dfltcmd);
- X#ifdef VERIFY
- X printcmd();
- X#endif
- X putchar('\n') FLUSH;
- X if (*buf == 'h') {
- X fputs(u_help_thread,stdout);
- X#ifdef VERBOSE
- X IF(verbose)
- X {
- X if (ThreadedGroup)
- X fputs("\
- XType + to enter select thread mode using all the unread articles.\n\
- X(The selected threads will be marked as unread and displayed as usual.)\n\
- X",stdout) FLUSH;
- X fputs("\
- XType a to mark all articles in this group as unread.\n\
- XType n to change nothing.\n\
- X",stdout) FLUSH;
- X }
- X ELSE
- X#endif
- X#ifdef TERSE
- X {
- X if (ThreadedGroup)
- X fputs("\
- X+ to select threads from the unread.\n\
- X",stdout) FLUSH;
- X fputs("\
- Xa to mark all articles unread.\n\
- Xn to change nothing.\n\
- X",stdout) FLUSH;
- X }
- X#endif
- X goto reask_unread;
- X }
- X else if (*buf == 'n' || *buf == 'q') {
- X return AS_ASK;
- X }
- X else if (*buf == 't' && *dfltcmd == 't')
- X follow_thread('u');
- X else if (*buf == 's' && *dfltcmd == 't') {
- X follow_thread('U');
- X }
- X else if (*buf == 'a') {
- X check_first(absfirst);
- X for (i = absfirst; i <= lastart; i++) {
- X onemore(i); /* mark as unread */
- X }
- X scan_all_roots = FALSE;
- X count_roots(FALSE);
- X if (art > lastart) {
- X first_art();
- X }
- X }
- X else if (ThreadedGroup && *buf == '+') {
- X *buf = 'U';
- X goto select_threads;
- X }
- X else {
- X fputs(hforhelp,stdout) FLUSH;
- X settle_down();
- X goto reask_unread;
- X }
- X return AS_NORM;
- X }
- X case '[': /* goto parent article */
- X case '{': /* goto thread's root article */
- X if (p_art) {
- X if (!p_art->parent) {
- X if (p_art == p_articles + p_roots[p_art->root].articles) {
- X register char *cp = (*buf=='['?"parent":"root");
- X#ifdef VERBOSE
- X IF(verbose)
- X fprintf(stdout,"\n\
- XThere is no %s article prior to this one.\n",cp) FLUSH;
- X ELSE
- X#endif
- X#ifdef TERSE
- X fprintf(stdout,"\nNo prior %s.\n",cp) FLUSH;
- X#endif
- X return AS_ASK;
- X }
- X *buf = '{';
- X p_art--;
- X }
- X else
- X p_art += p_art->parent;
- X
- X if (*buf == '{')
- X while (p_art->parent)
- X p_art += p_art->parent;
- X
- X art = p_art->num;
- X reread = TRUE;
- X return AS_NORM;
- X }
- Xnot_threaded:
- X if (ThreadedGroup) {
- X#ifdef VERBOSE
- X IF(verbose)
- X fputs("\nThis article is not threaded.\n",stdout) FLUSH;
- X ELSE
- X#endif
- X#ifdef TERSE
- X fputs("\nUnthreaded article.\n",stdout) FLUSH;
- X#endif
- X return AS_ASK;
- X }
- Xgroup_unthreaded:
- X#ifdef VERBOSE
- X IF(verbose)
- X fputs("\nThis group is not threaded.\n",stdout) FLUSH;
- X ELSE
- X#endif
- X#ifdef TERSE
- X fputs("\nUnthreaded group.\n",stdout) FLUSH;
- X#endif
- X return AS_ASK;
- X case ']': /* goto child article */
- X case '}': /* goto thread's leaf article */
- X if (p_art) {
- X if (!(p_art++)->child_cnt) {
- X PACKED_ARTICLE *root_limit = upper_limit(p_art-1,FALSE);
- X
- X if (p_art == root_limit) {
- X#ifdef VERBOSE
- X IF(verbose)
- X fputs("\n\
- XThis is the last leaf in this tree.\n",stdout) FLUSH;
- X ELSE
- X#endif
- X#ifdef TERSE
- X fputs("\nLast leaf.\n",stdout) FLUSH;
- X#endif
- X p_art--;
- X return AS_ASK;
- X }
- X if (*buf == ']')
- X *buf = '}';
- X else {
- X while (++p_art != root_limit && p_art->parent)
- X ;
- X p_art--;
- X *buf = ' ';
- X }
- X }
- X if( *buf == '}' )
- X while (p_art->child_cnt)
- X p_art++;
- X
- X art = p_art->num;
- X reread = TRUE;
- X return AS_NORM;
- X }
- X goto not_threaded;
- X case 'T':
- X if (p_art) {
- X sprintf(buf,"T%ld\t# %s",(long)p_roots[p_art->root].root_num,
- X subject_ptrs[p_art->subject]);
- X fputs(buf,stdout);
- X kf_append(buf);
- X *buf = 'J';
- X goto follow_threads;
- X }
- X goto not_threaded;
- X case 'K':
- X if (p_art) {
- X /* first, write kill-subject command */
- X (void)art_search(buf, (sizeof buf), TRUE);
- X art = curr_art;
- X p_art = curr_p_art;
- X *buf = 'k'; /* then take care of any prior subjs */
- X goto follow_threads;
- X }
- X goto normal_search;
- X case ',': /* kill this node and all descendants */
- X mark_as_read();
- X *buf = 'K';
- X case 'k': /* kill current subject # (e.g. [1]) */
- X case 'J': /* Junk all nodes in this thread */
- X if (!ThreadedGroup) {
- X *buf = 'k';
- X goto normal_search;
- X }
- Xfollow_threads:
- X follow_thread(*buf);
- X if (!reread && !toread[ng])
- X return AS_CLEAN;
- X if (!reread && selected_root_cnt && !selected_count)
- X goto select_threads;
- X return AS_NORM;
- X case 't':
- X carriage_return();
- X#ifndef CLEAREOL
- X erase_eol(); /* erase the prompt */
- X#else
- X if (erase_screen && can_home_clear)
- X clear_rest();
- X else
- X erase_eol(); /* erase the prompt */
- X#endif /* CLEAREOL */
- X fflush(stdout);
- X page_line = 1;
- X p_art = curr_p_art;
- X entire_tree();
- X return AS_ASK;
- X case ':': /* execute command on selected articles */
- X if (!ThreadedGroup) {
- X goto group_unthreaded;
- X }
- X page_line = 1;
- X if (!use_selected())
- X return AS_INP;
- X putchar('\n');
- X art = curr_art;
- X p_art = curr_p_art;
- X return AS_ASK;
- X#endif /* USETHREADS */
- X case 'p': /* find previous unread article */
- X#ifdef USETHREADS
- X if (ThreadedGroup) {
- X goto backtrack_threads;
- X }
- X#endif
- X do {
- X if (art <= firstart)
- X break;
- X art--;
- X#ifdef SERVER
- X } while (was_read(art) || nntpopen(art,GET_HEADER) == Nullfp);
- X#else
- X } while (was_read(art) || artopen(art) == Nullfp);
- X#endif
- X#ifdef ARTSEARCH
- X srchahead = 0;
- X#endif
- X return AS_NORM;
- X case 'P': /* goto previous article */
- X#ifdef USETHREADS
- X if (ThreadedGroup) {
- Xbacktrack_threads:
- X backtrack_thread( *buf );
- X art++; /* prepare for art-- below */
- X }
- X#endif
- X if (art > absfirst)
- X art--;
- X else {
- X#ifdef VERBOSE
- X IF(verbose)
- X fprintf(stdout,"\n\
- XThere are no%s articles prior to this one.\n\
- X",*buf=='P'?nullstr:" unread") FLUSH;
- X ELSE
- X#endif
- X#ifdef TERSE
- X fprintf(stdout,"\n\
- XNo previous%s articles\n\
- X",*buf=='P'?nullstr:" unread") FLUSH;
- X#endif
- X art = curr_art;
- X#ifdef USETHREADS
- X p_art = curr_p_art;
- X#endif
- X return AS_ASK;
- X }
- X reread = TRUE;
- X#ifdef ARTSEARCH
- X srchahead = 0;
- X#endif
- X return AS_NORM;
- X case '-':
- X if (recent_art >= 0) {
- X#ifdef USETHREADS
- X p_art = recent_p_art;
- X#endif
- X art = recent_art;
- X reread = TRUE;
- X#ifdef ARTSEARCH
- X srchahead = -(srchahead != 0);
- X#endif
- X return AS_NORM;
- X }
- X else {
- X exit_code = NG_MINUS;
- X return AS_CLEAN;
- X }
- X case 'n': /* find next unread article? */
- X#ifdef USETHREADS
- X if (ThreadedGroup) {
- X goto follow_threads;
- X }
- X#endif
- X if (art > lastart) {
- X if (!toread[ng])
- X return AS_CLEAN;
- X art = firstart;
- X }
- X#ifdef ARTSEARCH
- X else if (scanon && srchahead) {
- X *buf = Ctl('n');
- X goto normal_search;
- X }
- X#endif
- X else
- X art++;
- X
- X#ifdef ARTSEARCH
- X srchahead = 0;
- X#endif
- X return AS_NORM;
- X case 'N': /* goto next article */
- X#ifdef USETHREADS
- X if (ThreadedGroup) {
- X goto follow_threads;
- X }
- X#endif
- X if (art > lastart)
- X art = absfirst;
- X else
- X art++;
- X if (art <= lastart)
- X reread = TRUE;
- X#ifdef ARTSEARCH
- X srchahead = 0;
- X#endif
- X return AS_NORM;
- X case '$':
- X art = lastart+1;
- X forcelast = TRUE;
- X#ifdef USETHREADS
- X p_art = Nullart;
- X#endif
- X#ifdef ARTSEARCH
- X srchahead = 0;
- X#endif
- X return AS_NORM;
- X case '1': case '2': case '3': /* goto specified article */
- X case '4': case '5': case '6': /* or do something with a range */
- X case '7': case '8': case '9': case '.':
- X forcelast = TRUE;
- X switch (numnum()) {
- X case NN_INP:
- X return AS_INP;
- X case NN_ASK:
- X return AS_ASK;
- X case NN_REREAD:
- X reread = TRUE;
- X#ifdef ARTSEARCH
- X if (srchahead)
- X srchahead = -1;
- X#endif
- X break;
- X case NN_NORM:
- X if (was_read(art)) {
- X#ifdef USETHREADS
- X first_art();
- X#else
- X art = firstart;
- X#endif
- X pad(just_a_sec/3);
- X }
- X else {
- X putchar('\n');
- X return AS_ASK;
- X }
- X break;
- X }
- X return AS_NORM;
- X case Ctl('k'):
- X edit_kfile();
- X return AS_ASK;
- X#ifndef USETHREADS
- X case 'K':
- X case 'k':
- X#endif
- X case Ctl('n'): /* search for next article with same subject */
- X#ifdef USETHREADS
- X if (ThreadedGroup) {
- X goto follow_threads;
- X }
- X#endif
- X case Ctl('p'): /* search for previous article with same subject */
- X#ifdef USETHREADS
- X if (ThreadedGroup) {
- X goto backtrack_threads;
- X }
- X#endif
- X case '/': case '?':
- Xnormal_search:
- X#ifdef ARTSEARCH
- X { /* search for article by pattern */
- X char cmd = *buf;
- X
- X reread = TRUE; /* assume this */
- X page_line = 1;
- X switch (art_search(buf, (sizeof buf), TRUE)) {
- X case SRCH_ERROR:
- X art = curr_art;
- X return AS_ASK;
- X case SRCH_ABORT:
- X art = curr_art;
- X return AS_INP;
- X case SRCH_INTR:
- X#ifdef VERBOSE
- X IF(verbose)
- X printf("\n(Interrupted at article %ld)\n",(long)art) FLUSH;
- X ELSE
- X#endif
- X#ifdef TERSE
- X printf("\n(Intr at %ld)\n",(long)art) FLUSH;
- X#endif
- X art = curr_art;
- X /* restore to current article */
- X return AS_ASK;
- X case SRCH_DONE:
- X fputs("done\n",stdout) FLUSH;
- X pad(just_a_sec/3); /* 1/3 second */
- X if (!srchahead) {
- X art = curr_art;
- X return AS_ASK;
- X }
- X#ifdef USETHREADS
- X first_art();
- X#else
- X art = firstart;
- X#endif
- X reread = FALSE;
- X return AS_NORM;
- X case SRCH_SUBJDONE:
- X#ifdef UNDEF
- X fputs("\n\n\n\nSubject not found.\n",stdout) FLUSH;
- X pad(just_a_sec/3); /* 1/3 second */
- X#endif
- X#ifdef USETHREADS
- X first_art();
- X#else
- X art = firstart;
- X#endif
- X reread = FALSE;
- X return AS_NORM;
- X case SRCH_NOTFOUND:
- X fputs("\n\n\n\nNot found.\n",stdout) FLUSH;
- X art = curr_art; /* restore to current article */
- X return AS_ASK;
- X case SRCH_FOUND:
- X if (cmd == Ctl('n') || cmd == Ctl('p'))
- X oldsubject = TRUE;
- X break;
- X }
- X return AS_NORM;
- X }
- X#else
- X buf[1] = '\0';
- X notincl(buf);
- X return AS_ASK;
- X#endif
- X case 'u': /* unsubscribe from this newsgroup? */
- X rcchar[ng] = NEGCHAR;
- X return AS_CLEAN;
- X case 'M':
- X#ifdef DELAYMARK
- X if (art <= lastart) {
- X delay_unmark(art);
- X printf("\nArticle %ld will return.\n",(long)art) FLUSH;
- X }
- X#else
- X notincl("M");
- X#endif
- X return AS_ASK;
- X case 'm':
- X if (art <= lastart) {
- X unmark_as_read();
- X printf("\nArticle %ld marked as still unread.\n",(long)art) FLUSH;
- X }
- X return AS_ASK;
- X case 'c': /* catch up */
- X reask_catchup:
- X#ifdef VERBOSE
- X IF(verbose)
- X in_char("\nDo you really want to mark everything as read? [yn] ",
- X 'C');
- X ELSE
- X#endif
- X#ifdef TERSE
- X in_char("\nReally? [ynh] ", 'C');
- X#endif
- X setdef(buf,"y");
- X#ifdef VERIFY
- X printcmd();
- X#endif
- X putchar('\n') FLUSH;
- X if (*buf == 'h') {
- X#ifdef VERBOSE
- X IF(verbose)
- X fputs("\
- XType y or SP to mark all articles as read.\n\
- XType n to leave articles marked as they are.\n\
- XType u to mark everything read and unsubscribe.\n\
- X",stdout) FLUSH;
- X ELSE
- X#endif
- X#ifdef TERSE
- X fputs("\
- Xy or SP to mark all read.\n\
- Xn to forget it.\n\
- Xu to mark all and unsubscribe.\n\
- X",stdout) FLUSH;
- X#endif
- X goto reask_catchup;
- X }
- X else if (*buf == 'n' || *buf == 'q') {
- X return AS_ASK;
- X }
- X else if (*buf != 'y' && *buf != 'u') {
- X fputs(hforhelp,stdout) FLUSH;
- X settle_down();
- X goto reask_catchup;
- X }
- X for (i = firstart; i <= lastart; i++) {
- X oneless(i); /* mark as read */
- X }
- X#ifdef USETHREADS
- X selected_root_cnt = selected_count = 0;
- X#endif
- X#ifdef DELAYMARK
- X if (dmfp)
- X yankback();
- X#endif
- X if (*buf == 'u') {
- X rcchar[ng] = NEGCHAR;
- X return AS_CLEAN;
- X }
- X#ifdef USETHREADS
- X p_art = Nullart;
- X selected_count = 0;
- X#endif
- X art = lastart+1;
- X forcelast = FALSE;
- X return AS_NORM;
- X case 'Q':
- X exit_code = NG_ASK;
- X /* FALL THROUGH */
- X case 'q': /* go back up to newsgroup level? */
- X return AS_CLEAN;
- X case 'j':
- X putchar('\n') FLUSH;
- X if (art <= lastart)
- X mark_as_read();
- X return AS_ASK;
- X case 'h': { /* help? */
- X int cmd;
- X
- X if ((cmd = help_art()) > 0)
- X pushchar(cmd);
- X return AS_ASK;
- X }
- X case '&':
- X if (switcheroo()) /* get rest of command */
- X return AS_INP; /* if rubbed out, try something else */
- X return AS_ASK;
- X case '#':
- X#ifdef VERBOSE
- X IF(verbose)
- X printf("\nThe last article is %ld.\n",(long)lastart) FLUSH;
- X ELSE
- X#endif
- X#ifdef TERSE
- X printf("\n%ld\n",(long)lastart) FLUSH;
- X#endif
- X return AS_ASK;
- X#ifdef USETHREADS
- X case '+': /* enter thread selection mode */
- X if (ThreadedGroup) {
- Xselect_threads:
- X *buf = select_thread(*buf);
- X if (*buf == 'q') {
- X putchar( '\n' ) FLUSH;
- X return AS_ASK;
- X }
- X if (*buf == 'Q') {
- X exit_code = NG_ASK;
- X return AS_CLEAN;
- X }
- X if (*buf == 'N' || !toread[ng])
- X return AS_CLEAN;
- X return AS_NORM;
- X }
- X /* FALLTHROUGH */
- X#endif
- X case '=': { /* list subjects */
- X char tmpbuf[256];
- X ART_NUM oldart = art;
- X int cmd;
- X char *subjline = getval("SUBJLINE",Nullch);
- X#ifndef CACHESUBJ
- X char *s;
- X#endif
- X
- X page_init();
- X#ifdef CACHESUBJ
- X if (!subj_list)
- X fetchsubj(art,TRUE,FALSE);
- X#endif
- X for (i=firstart; i<=lastart && !int_count; i++) {
- X#ifdef CACHESUBJ
- X if (!was_read(i) &&
- X (subj_list[OFFSET(i)] != Nullch || fetchsubj(i,FALSE,FALSE)) &&
- X *subj_list[OFFSET(i)] ) {
- X sprintf(tmpbuf,"%5ld ", i);
- X if (subjline) {
- X art = i;
- X interp(tmpbuf + 6, (sizeof tmpbuf) - 6, subjline);
- X }
- X else
- X safecpy(tmpbuf + 6, subj_list[OFFSET(i)],
- X (sizeof tmpbuf) - 6);
- X if (cmd = print_lines(tmpbuf,NOMARKING)) {
- X if (cmd > 0)
- X pushchar(cmd);
- X break;
- X }
- X }
- X#else
- X if (!was_read(i) && (s = fetchsubj(i,FALSE,FALSE)) && *s) {
- X sprintf(tmpbuf,"%5ld ", i);
- X if (subjline) { /* probably fetches it again! */
- X art = i;
- X interp(tmpbuf + 6, (sizeof tmpbuf) - 6, subjline);
- X }
- X else
- X safecpy(tmpbuf + 6, s, (sizeof tmpbuf) - 6);
- X if (cmd = print_lines(tmpbuf,NOMARKING)) {
- X if (cmd > 0)
- X pushchar(cmd);
- X break;
- X }
- X }
- X#endif
- X }
- X int_count = 0;
- X art = oldart;
- X return AS_ASK;
- X }
- X case '^':
- X#ifdef USETHREADS
- X first_art();
- X#else
- X art = firstart;
- X#endif
- X#ifdef ARTSEARCH
- X srchahead = 0;
- X#endif
- X return AS_NORM;
- X#if defined(CACHESUBJ) && defined(DEBUGGING)
- X case 'D':
- X printf("\nFirst article: %ld\n",(long)firstart) FLUSH;
- X if (!subj_list)
- X fetchsubj(art,TRUE,FALSE);
- X if (subj_list != Null(char **)) {
- X for (i=1; i<=lastart && !int_count; i++) {
- X if (subj_list[OFFSET(i)])
- X printf("%5ld %c %s\n",
- X i, (was_read(i)?'y':'n'), subj_list[OFFSET(i)]) FLUSH;
- X }
- X }
- X int_count = 0;
- X return AS_ASK;
- X#endif
- X case 'v':
- X if (art <= lastart) {
- X reread = TRUE;
- X do_hiding = FALSE;
- X }
- X return AS_NORM;
- X#ifdef ROTATION
- X case Ctl('x'):
- X#endif
- X case Ctl('r'):
- X#ifdef ROTATION
- X rotate = (*buf==Ctl('x'));
- X#endif
- X if (art <= lastart)
- X reread = TRUE;
- X return AS_NORM;
- X#ifdef ROTATION
- X case 'X':
- X rotate = !rotate;
- X /* FALL THROUGH */
- X#else
- X case Ctl('x'):
- X case 'x':
- X case 'X':
- X notincl("x");
- X return AS_ASK;
- X#endif
- X case 'l': case Ctl('l'): /* refresh screen */
- X if (art <= lastart) {
- X reread = TRUE;
- X clear();
- X do_fseek = TRUE;
- X artline = topline;
- X if (artline < 0)
- X artline = 0;
- X }
- X return AS_NORM;
- X case 'b': case Ctl('b'): /* back up a page */
- X if (art <= lastart) {
- X ART_LINE target;
- X
- X reread = TRUE;
- X clear();
- X do_fseek = TRUE;
- X target = topline - (LINES - 2);
- X artline = topline;
- X if (artline >= 0) do {
- X artline--;
- X } while(artline >= 0 && artline > target && vrdary(artline-1) >= 0);
- X topline = artline;
- X if (artline < 0)
- X artline = 0;
- X }
- X return AS_NORM;
- X case '!': /* shell escape */
- X if (escapade())
- X return AS_INP;
- X return AS_ASK;
- X case 'C': {
- X cancel_article();
- X return AS_ASK;
- X }
- X case 'R':
- X case 'r': { /* reply? */
- X reply();
- X return AS_ASK;
- X }
- X case 'F':
- X case 'f': { /* followup command */
- X followup();
- X forcegrow = TRUE; /* recalculate lastart */
- X return AS_ASK;
- X }
- X case '|':
- X case 'w': case 'W':
- X case 's': case 'S': /* save command */
- X case 'e': /* extract command */
- X if (save_article() == SAVE_ABORT)
- X return AS_INP;
- X int_count = 0;
- X return AS_ASK;
- X case 'E':
- X if (uu_out != Nullfp) {
- X uud_end();
- X }
- X return AS_ASK;
- X#ifdef DELAYMARK
- X case 'Y': /* yank back M articles */
- X yankback();
- X#ifdef USETHREADS
- X first_art();
- X#else
- X art = firstart; /* from the beginning */
- X#endif
- X return AS_NORM; /* pretend nothing happened */
- X#endif
- X#ifdef STRICTCR
- X case '\n':
- X fputs(badcr,stdout) FLUSH;
- X return AS_ASK;
- X#endif
- X default:
- X printf("\n%s",hforhelp) FLUSH;
- X settle_down();
- X return AS_ASK;
- X }
- X}
- X
- X#ifdef MAILCALL
- X/* see if there is any mail */
- X
- Xvoid
- Xsetmail()
- X{
- X if (! (mailcount++)) {
- X char *mailfile = filexp(getval("MAILFILE",MAILFILE));
- X
- X if (stat(mailfile,&filestat) < 0 || !filestat.st_size
- X || filestat.st_atime > filestat.st_mtime)
- X mailcall = nullstr;
- X else
- X mailcall = getval("MAILCALL","(Mail) ");
- X }
- X mailcount %= 10; /* check every 10 articles */
- X}
- X#endif
- X
- Xvoid
- Xsetdfltcmd()
- X{
- X#ifdef USETHREADS
- X if (toread[ng] == unthreaded) {
- X#else
- X if (!toread[ng]) {
- X#endif
- X if (art > lastart)
- X dfltcmd = "qnp";
- X else
- X dfltcmd = "npq";
- X }
- X else {
- X#ifdef USETHREADS
- X if (selected_root_cnt && !selected_count)
- X dfltcmd = "+npq";
- X else
- X# ifdef ARTSEARCH
- X if (!ThreadedGroup && srchahead)
- X dfltcmd = "^Nnpq";
- X else
- X# endif
- X#else
- X# ifdef ARTSEARCH
- X if (srchahead)
- X dfltcmd = "^Nnpq";
- X else
- X# endif
- X#endif
- X dfltcmd = "npq";
- X }
- X}
- END_OF_FILE
- if test 34884 -ne `wc -c <'ng.c'`; then
- echo shar: \"'ng.c'\" unpacked with wrong size!
- fi
- # end of 'ng.c'
- fi
- echo shar: End of archive 4 \(of 14\).
- cp /dev/null ark4isdone
- MISSING=""
- for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 14 archives.
- rm -f ark[1-9]isdone ark[1-9][0-9]isdone
- else
- echo You still must unpack the following archives:
- echo " " ${MISSING}
- fi
- exit 0
-